/*
	dump_pattern.cc	Dump pattern database
	Copyright (c) 2001, 2002, 2003, 2004 Kriang Lerdsuwanakij
	email:		lerdsuwa@users.sourceforge.net

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "config.h"

#include <exception>
#include <stdexcept>
#include <fstream>
#include <sstream>

#include <cstring>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "pattern.h"

#include "gtstream.h"

#ifdef _
#undef _
#endif

#ifdef N_
#undef N_
#endif

#include <libintl.h>
#define _(x) gettext(x)
#define N_(x) (x)

// Grab version number in VERSION variable
#undef VERSION
char *
#include "scripts/version"
;

const char *prog_name = "dump_pattern";
const char *prog_ver = VERSION;

int num_log_move_index = 0;
int log_move_index[num_move_index];

// Return true if pattern for move_index should be displayed
bool is_log_move_index(int move_index)
{
	for (int i = 0; i < num_log_move_index; ++i) {
		if (move_index == log_move_index[i])
			return true;
	}
	return false;
}

int main_real(int argc, char *argv[])
{
	use_private_files(true);
	pattern_table_init();

	if (argc == 1) {
		gtout(std::cout, _("%$ %$ - Pattern dumper\n")) << prog_name << prog_ver;
		std::cout << _("(c) 2001, 2002, 2003 Kriang Lerdsuwanakij\n\n");
		gtout(std::cout, _("Usage:   %$ PATTERN MOVE_INDEX\n\n")) << prog_name;
		return 0;
	}
	else if (argc < 3)
		throw std::runtime_error(_("bad arguments"));

	pattern_t pattern = PATTERN_UNKNOWN;
	if (strcmp(argv[1], "row1") == 0) {
		pattern = PATTERN_ROW1;
	}
	else if (strcmp(argv[1], "row2") == 0) {
		pattern = PATTERN_ROW2;
	}
	else if (strcmp(argv[1], "row3") == 0) {
		pattern = PATTERN_ROW3;
	}
	else if (strcmp(argv[1], "row4") == 0) {
		pattern = PATTERN_ROW4;
	}
	else if (strcmp(argv[1], "diag1") == 0) {
		pattern = PATTERN_DIAG1;
	}
	else if (strcmp(argv[1], "diag2") == 0) {
		pattern = PATTERN_DIAG2;
	}
	else if (strcmp(argv[1], "diag3") == 0) {
		pattern = PATTERN_DIAG3;
	}
	else if (strcmp(argv[1], "diag4") == 0) {
		pattern = PATTERN_DIAG4;
	}
	else if (strcmp(argv[1], "diag5") == 0) {
		pattern = PATTERN_DIAG5;
	}
	else if (strcmp(argv[1], "edge-x") == 0) {
		pattern = PATTERN_EDGE_X;
	}
	else if (strcmp(argv[1], "corner5x2") == 0) {
		pattern = PATTERN_CORNER5X2;
	}
	else {
		throw std::runtime_error(_("bad pattern name"));
	}

	int handle = open(get_pattern_file(pattern), O_RDONLY);
	if (handle == -1) {
		gtstream bufstr;
		gtout(bufstr, _("cannot open file %$\n"))
			<< get_pattern_file(pattern);
		throw std::runtime_error(bufstr.str());
	}

	for (int i = 2; i < argc; ++i) {
		char *end_ptr;
		int p = strtol(argv[i], &end_ptr, 10);
		if (p >= 0 && p < num_move_index && *end_ptr == '\0') {
			log_move_index[num_log_move_index] = p;
			num_log_move_index++;
		}
	}

	raw_pattern_info *pat = new raw_pattern_info[get_pattern_size(pattern)];

	for (int move_index = 0; move_index < num_move_index; ++move_index) {
		int size = sizeof(raw_pattern_info) * get_pattern_size(pattern);
		if (read(handle, pat, size) != size) {
			close(handle);

			gtstream bufstr;
			gtout(bufstr, _("cannot open file %$\n"))
				<< get_pattern_file(pattern);
			throw std::runtime_error(bufstr.str());
		}

		if (!is_log_move_index(move_index))
			continue;

		for (int i = 0; i < pow_3[get_pattern_piece(pattern)]; ++i) {
			std::cout << move_index << "  [";
			show_pattern(pattern, i);
			std::cout << "]  " << static_cast<int>(pattern_table[pattern][move_index][i]);

			std::cout << "  B:" << pat[i].black_win << "  W:" << pat[i].white_win;
			if (pat[i].black_win + pat[i].white_win == 0)
				std::cout << "    *";
			std::cout << '\n';
		}
	}

	close(handle);
	return 0;
}

int main(int argc, char *argv[])
{
	try {
		return main_real(argc, argv);
	}
	catch (std::exception &e) {
		std::cout << std::flush;
		gtout(std::cerr, _("%$: %$\n")) << prog_name << e.what();
	}
	catch (const char *s) {
		std::cout << std::flush;
		gtout(std::cerr, _("%$: exception %$\n")) << prog_name << s;
	}
	catch (...) {
		std::cout << std::flush;
		gtout(std::cerr, _("%$: unknown exception\n")) << prog_name;
	}
	return 1;
}
